﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using System.Diagnostics;

namespace Projektarbete
{
    delegate void VoidPointer();
    delegate void VoidPointerUpdateLightmap(Point playerPosition, int octant, int depth, float slopeA, float slopeB);
    delegate void VoidPointerPointArg(Point point);
    delegate void VoidPointerIntArg(int intArg);
    delegate void VoidPointerItemArg(Item item);
    delegate void VoidPointerTileArgTileArg(Tile item, Tile item2);
    delegate bool BoolPointerItemArg(Item item);
    delegate void VoidPointer2DItemArrayArg(Item[][] item);
    delegate void VoidPointerMerchantBaseArg(MerchantBase merchant);

    class MainScreen : Screen
    {
        GraphicsDevice graphicsDevice;

        Dictionary<string, NetPlayer> playerDict;
        //Player Player;

        bool isClient;
        bool isServer;
        bool drawMap;

        Random random;

        byte frameCounter;

        public MainScreen(EventHandler ScreenEvent, GraphicsDevice graphicsDevice)
            : base(ScreenEvent)
        {
            this.graphicsDevice = graphicsDevice;

            Point topLeft = Point.Zero;
            Point bottomRight = Point.Zero;
            #region old code
            /*GenerateMap.generateMap(ref map, 8000, ref topLeft, ref bottomRight);
            GenerateMap.FixPillars(ref map, topLeft, bottomRight, new Random(), 0.9);

            Tile[][] ZeroedMap = GenerateMap.ZeroPosition(ref map, topLeft, bottomRight);

            Map = new Map(ZeroedMap, Global.Spritesheet);

            Vector2 spawnPosition = Vector2.Zero;

            spawnPosition = new Vector2(random.Next(3, 100) * 24, random.Next(3, 100) * 24);*/
            #endregion

            random = Global.random;

            Point spawnPosition = Point.Zero;

            MapHandler.SetupMap(FileIO.LoadMapFromImage("map.png", graphicsDevice, true, ref spawnPosition), Global.Spritesheet);

            PopupManager.Initialize();

            AIManager.SetUp();
            AIManager.AddEnemy(new EnemyBase(Global.Playersheet, new Vector2(240, 480), 100, 1));

            MerchantBase merchant = new MerchantBase(Global.LoadTexture2D("Tilesheets/Merchants/Merchant"), new Vector2(240, 240));
            merchant.inventory.AddItem(new ItemPresets.HealthPotionBad());
            merchant.inventory.AddItem(new ItemPresets.HealthPotionBad());
            merchant.inventory.AddItem(new ItemPresets.HealthPotionBad());
            merchant.inventory.AddItem(new ItemPresets.HealthPotionBad());
            merchant.inventory.AddItem(new ItemPresets.HealthPotionBad());
            merchant.inventory.AddItem(new ItemPresets.HealthPotionBad());
            merchant.inventory.AddItem(new ItemPresets.HealthPotionBad());
            merchant.inventory.AddItem(new ItemPresets.HealthPotionNormal());
            merchant.inventory.AddItem(new ItemPresets.HealthPotionBad());
            merchant.inventory.AddItem(new ItemPresets.HealthPotionBad());
            merchant.inventory.AddItem(new ItemPresets.HealthPotionBad());
            merchant.inventory.AddItem(new ItemPresets.HealthPotionNormal());
            merchant.inventory.AddItem(new ItemPresets.HealthPotionNormal());
            merchant.inventory.AddItem(new ItemPresets.HealthPotionNormal());
            merchant.inventory.AddItem(new ItemPresets.HealthPotionBad());
            merchant.inventory.AddItem(new ItemPresets.HealthPotionNormal());
            merchant.inventory.AddItem(new ItemPresets.HealthPotionNormal());
            merchant.inventory.AddItem(new ItemPresets.HealthPotionTerrible());
            merchant.inventory.AddItem(new ItemPresets.HealthPotionTerrible());
            merchant.inventory.AddItem(new ItemPresets.HealthPotionNormal());
            merchant.inventory.AddItem(new ItemPresets.HealthPotionNormal());
            merchant.inventory.AddItem(new ItemPresets.HealthPotionTerrible());
            merchant.inventory.AddItem(new ItemPresets.HealthPotionTerrible());
            merchant.inventory.AddItem(new ItemPresets.HealthPotionBad());
            merchant.inventory.AddItem(new ItemPresets.HealthPotionBad());
            merchant.inventory.AddItem(new ItemPresets.HealthPotionTerrible());
            merchant.inventory.AddItem(new ItemPresets.HealthPotionTerrible());
            AIManager.AddMerchant(merchant);

            string name = "";
            for (int i = 0; i < 10; i++)
                name = string.Concat(name, ((char)random.Next(65, 90)).ToString());
            Player.Initialize(name, 100, 12f, new Vector2(spawnPosition.X * 24, spawnPosition.Y * 24), Global.Playersheet, Global.KeyConfig);
            playerDict = new Dictionary<string, NetPlayer>();

            HUD.Initialize(graphicsDevice);


            #region shit
            Player.inventory.AddItemDiscreetly(new ItemPresets.HealthPotionBad());
            Player.inventory.AddItemDiscreetly(new ItemPresets.HealthPotionBad());
            Player.inventory.AddItemDiscreetly(new ItemPresets.HealthPotionBad());
            Player.inventory.AddItemDiscreetly(new ItemPresets.HealthPotionTerrible());
            Player.inventory.AddItemDiscreetly(new ItemPresets.HealthPotionNormal());
            Player.inventory.AddItemDiscreetly(new ItemPresets.ManaPotionBad());
            Player.inventory.AddItemDiscreetly(new ItemPresets.ManaPotionTerrible());
            Player.inventory.AddItemDiscreetly(new ItemPresets.ManaPotionNormal());
            Player.inventory.AddItemDiscreetly(new ItemPresets.HealthPotionBad());
            Player.inventory.AddItemDiscreetly(new ItemPresets.HealthPotionTerrible());
            Player.inventory.AddItemDiscreetly(new ItemPresets.HealthPotionBad());
            Player.inventory.AddItemDiscreetly(new ItemPresets.HealthPotionBad());
            Player.inventory.AddItemDiscreetly(new ItemPresets.HealthPotionBad()); 
            Player.inventory.AddItemDiscreetly(new ItemPresets.HealthPotionNormal());
            Player.inventory.AddItemDiscreetly(new ItemPresets.ManaPotionBad());
            Player.inventory.AddItemDiscreetly(new ItemPresets.ManaPotionTerrible());
            Player.inventory.AddItemDiscreetly(new ItemPresets.ManaPotionNormal());
            Player.inventory.AddItemDiscreetly(new ItemPresets.HealthPotionBad());
            Player.inventory.AddItemDiscreetly(new ItemPresets.HealthPotionTerrible());
            Player.inventory.AddItemDiscreetly(new ItemPresets.HealthPotionBad());
            Player.inventory.AddItemDiscreetly(new ItemPresets.HealthPotionBad());
            Player.inventory.AddItemDiscreetly(new ItemPresets.HealthPotionBad());
            Player.inventory.AddItemDiscreetly(new ItemPresets.ChestSuckass());
            #endregion

            Player.gold = 9001;
            Player.IncreaseStat(Player.Stats.Strength, 2);
            Player.IncreaseStat(Player.Stats.Strength, 1);
            Player.IncreaseStat(Player.Stats.Strength, 0);
            Player.IncreaseStat(Player.Stats.Strength, 3);

            Camera.Initialize(new Vector2(Player.position.X + 12, Player.position.Y + 12), new Vector2(800, 600), MapHandler.mapDimensions);
            Camera.UpdateMatrix(new Vector2(Player.position.X + 12, Player.position.Y + 12));

            HUD.RefreshMinimap(Global.ToTilePosition(Player.position));

            frameCounter = 0;
        }

        public override void Update(GameTime gameTime)
        {

            Player.Update();

            PopupManager.Update();

            HUD.Update();
            AIManager.Update(Player.position);

            //Kör det här var 3:e frame
            if (frameCounter % 3 == 0)
            {
                //currentHUD.Update(gameTime, Player, camera.zoom);
                BasicNet.UpdateLocalMovement(Player.position, Player.GetInteractedTiles());
                frameCounter = 0;
            }

            if (Input.IsNewPress(Keys.Space) && !isClient && !isServer)
            {
                isClient = true;
                //NET-TODO
                //BasicNet.JoinServer("78.69.14.91", Player, ref Map);
            }
            if (Input.IsNewPress(Keys.Enter) && !isClient && !isServer)
            {
                isServer = true;
                //NET-TODO
                //BasicNet.HostServer(ref Map);
            }

            if (Input.IsKeyDown(Keys.Escape))
                BasicNet.Disconnect();

            if (Input.IsNewPress(Keys.Q))
            {
                drawMap = true;
            }

            if (Input.IsNewPress(Keys.PageUp))
            {
                Camera.zoom += 0.05f;
                Camera.UpdateMatrix(new Vector2(Player.position.X + 12, Player.position.Y + 12));
            }

            if (Input.IsNewPress(Keys.PageDown))
            {
                Camera.zoom -= 0.05f;
                Camera.UpdateMatrix(new Vector2(Player.position.X + 12, Player.position.Y + 12));
            }

            BasicNet.Update(gameTime, frameCounter, playerDict);

            //Räkna frames för att kunna köra vissa funktioner var X:e frame
            frameCounter++;

            base.Update(gameTime);
        }

        public override void Draw(SpriteBatch spriteBatch)
        {
            if (drawMap && !isClient && !isServer)
            {
                spriteBatch.Begin();
                MapHandler.DrawMap(spriteBatch, Player.GetTiledPositionToVector2());
                spriteBatch.End();
            }
            else if (drawMap && isClient)
            {
                //DRAW WORLD THINGS WHICH WILL BE MOVED WITH CAMERS
                spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, null, null, null, null, Camera.getViewMatrix);
                MapHandler.DrawMap(spriteBatch, Player.GetTiledPositionToVector2());
                Player.DrawCharacter(spriteBatch);
                foreach (KeyValuePair<string, NetPlayer> playerEntry in playerDict)
                    playerEntry.Value.DrawCharacter(spriteBatch);

                AIManager.Draw(spriteBatch);
                MapHandler.DrawLightmap(spriteBatch);
                spriteBatch.End();

                //DRAW HUDS/OVERLAYS
                spriteBatch.Begin();
                HUD.Draw(spriteBatch, graphicsDevice);
                //DEBUG
                spriteBatch.DrawString(Global.BasicFont, Player.gold.ToString(), Vector2.Zero, Color.White);
                //!DEBUG

                PopupManager.Draw(spriteBatch, graphicsDevice);
                spriteBatch.End();
            }
            else if (drawMap && isServer)
            {
                spriteBatch.Begin();
                MapHandler.DrawMap(spriteBatch, Player.GetTiledPositionToVector2());
                foreach (KeyValuePair<string, NetPlayer> playerEntry in playerDict)
                    if (playerEntry.Value.IsPlaying)
                        playerEntry.Value.DrawCharacter(spriteBatch);
                spriteBatch.End();
            }
            else
            {
                spriteBatch.Begin();
                spriteBatch.DrawString(Global.BasicFont, "Press Space to join the server. Press Enter to host the server.", new Vector2(100, 200), Color.Red);
                spriteBatch.End();
            }

            base.Draw(spriteBatch);
        }
    }
}
